#include "Model.h"

Model::Model()
: m_IBOData(0), m_IBOID(0), m_iIBOs(0),
m_VBOData(0), m_VBOID(0), m_iVBOs(0)
{

}

Model::~Model()
{
	glDeleteBuffers(1, &m_IBOID);
	glDeleteBuffers(1, &m_VBOID);

	SAFE_DEL_ARRAY(m_IBOData);
	SAFE_DEL_ARRAY(m_VBOData);
}

__INT32 Model::LoadModel(__UINT32 iVertices, Vertex* aVertices, __UINT32 iIndices, GLuint* aIndices, __BOOL isReleaseData)
{
	m_iVBOs = iVertices;
	m_VBOData = new Vertex[m_iVBOs];
	memcpy(m_VBOData, aVertices, m_iVBOs*sizeof(Vertex));

	glGenBuffers(1, &m_VBOID);
	glBindBuffer(GL_ARRAY_BUFFER, m_VBOID);
	glBufferData(GL_ARRAY_BUFFER, m_iVBOs*sizeof(Vertex), m_VBOData, GL_STATIC_DRAW);
	glBindBuffer(GL_ARRAY_BUFFER, 0);

	if (aIndices)
	{
		m_iVBOs = iIndices;
		m_IBOData = new GLuint[m_iVBOs];
		memcpy(m_IBOData, aIndices, m_iVBOs*sizeof(GLuint));

		glGenBuffers(1, &m_IBOID);
		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_IBOID);
		glBufferData(GL_ELEMENT_ARRAY_BUFFER, m_iIBOs*sizeof(GLuint), m_IBOData, GL_STATIC_DRAW);
		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
	}

	if (isReleaseData)
	{
		SAFE_DEL_ARRAY(m_VBOData);
		SAFE_DEL_ARRAY(m_IBOData);
	}
	return 0;
}

__INT32 Model::LoadModel(char* strFileNFG, __BOOL isReleaseData)
{
	return LoadModel(0, 0, 0, 0, isReleaseData);
}

Vertex* Model::GetVBOData()
{
	Vertex* pOutput = 0;
	if (m_VBOData)
	{
		pOutput = new Vertex[m_iVBOs];
		memcpy(pOutput, m_VBOData, m_iVBOs*sizeof(Vertex));
		return pOutput;
	}
	return 0;
}

GLuint* Model::GetIBOData()
{
	GLuint* pOutput = 0;
	if (m_VBOData)
	{
		m_IBOData = new GLuint[m_iVBOs];
		memcpy(pOutput, m_IBOData, m_iVBOs*sizeof(GLuint));
		return pOutput;
	}
	return 0;
}

__INT32 Model::Render(Shader* sha)
{
	glBindBuffer(GL_ARRAY_BUFFER, m_VBOID);
	if (sha->a_VertextPos != -1)
	{
		glEnableVertexAttribArray(sha->a_VertextPos);
		glVertexAttribPointer(sha->a_VertextPos, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), 0);
	}
	else
	{
		return -1;
	}
	
	if (sha->a_VertTexCoord != -1)
	{
		glEnableVertexAttribArray(sha->a_VertTexCoord);
		glVertexAttribPointer(sha->a_VertTexCoord, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (char*)0 + sizeof(Vector3));
	}
	else
	{
		return -2;
	}

	if (sha->a_VertNorm != -1)
	{
		glEnableVertexAttribArray(sha->a_VertNorm);
		glVertexAttribPointer(sha->a_VertNorm, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (char*)0 + sizeof(Vector3) + sizeof(Vector2));
	}
	else
	{
		return -3;
	}
	
	if (sha->a_VertBiNorm != -1)
	{
		glEnableVertexAttribArray(sha->a_VertBiNorm);
		glVertexAttribPointer(sha->a_VertBiNorm, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (char*)0 + sizeof(Vector3)*2 + sizeof(Vector2));
	}
	else
	{
		return -4;
	}

	if (sha->a_VertTangent != -1)
	{
		glEnableVertexAttribArray(sha->a_VertTangent);
		glVertexAttribPointer(sha->a_VertTangent, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (char*)0 + sizeof(Vector3)* 3 + sizeof(Vector2));
	}
	else
	{
		return -5;
	}

	if (m_IBOData && m_iIBOs != 0)
	{
		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_IBOID);
	}

	return 0;
}

__VOID Model::Release()
{
	glBindBuffer(GL_ARRAY_BUFFER, 0);
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
}